package com.lz.util.db;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.HashMap;
import java.util.Map;
import java.util.logging.Level;
import java.util.logging.Logger;

import com.lz.util.log.LoggerUtil;


public class SequenceGenUtil {

	private static final Logger logger=LoggerUtil.getLogger(SequenceGenUtil.class.getName());
	
	
	//No need for any instance method
	private SequenceGenUtil(){
		maxValueToRotateMap=new HashMap(5);
		
		//put type and its max value to rotate
		maxValueToRotateMap.put("type", new Integer(10000));
		
	}
	
	private static SequenceGenUtil sequenceGenUtil=new SequenceGenUtil();
	
	private Map maxValueToRotateMap;
	   
    
    private Map getMaxValueToRotateMap(){return maxValueToRotateMap;}
   
	
	/**
	 * Type will indicate which sequence is to be picked up.
	 * @param conn
	 * @param type
	 * @return the next sequence value
	 */
	   public static synchronized String getNextId(Connection conn,String type){
           PreparedStatement ps=null;
           String id=null;
           try{
               
       
               ps=conn.prepareStatement(SQLConfig.getQuery("GETNEXT_ID"));
               ps.setString(1,type);
               ResultSet rs=ps.executeQuery();
               
               while(rs.next())
                   id=rs.getString("id");
               
               ps=conn.prepareStatement(SQLConfig.getQuery("UPDATENEXT_ID"));
               ps.setString(1,type);
               ps.execute();
       
           }
           catch(SQLException sqlex){
        	   
        	   logger.log(Level.SEVERE, sqlex.getMessage());
               throw new RuntimeException(sqlex);
           }
           finally{
        	   
        	   ps=null;
        	   
           }
           
           return id;
       }
	   
	   /**
	    * Gets the next sequence with rotation like if the sequence reaches 10000 again it is set to 1.
	    * @param conn
	    * @param type
	    * @return
	    */
	   public static synchronized String getNextIdWithRotation(Connection conn,String type){
           PreparedStatement ps=null;
           String id=null;
           try{
               
       
               ps=conn.prepareStatement(SQLConfig.getQuery("GETNEXT_ID"));
               ps.setString(1,type);
               ResultSet rs=ps.executeQuery();
               
               while(rs.next())
                   id=rs.getString("id");
               
               ps=conn.prepareStatement(SQLConfig.getQuery("UPDATENEXT_ID"));
               ps.setString(1,type);
               ps.execute();
       
     
           
           int maxValue=((Integer)sequenceGenUtil.getMaxValueToRotateMap().get(type)).intValue();
           int currValue=Integer.parseInt(id);
           
           if(currValue>maxValue){
               ps=conn.prepareStatement(SQLConfig.getQuery("RESET_ID"));
               ps.setString(1,type);
               ps.execute(); 
               return getNextId(conn,type);
           }
           
           rs.close();rs=null;
           ps.close();
           }
           catch(Exception sqlex){
        	   
        	   logger.log(Level.SEVERE, sqlex.getMessage());
               throw new RuntimeException(sqlex);
           }
           finally{
        	   
        	   ps=null;
        	   
           }
           
           return id;
       }
	 

}
